package com.smart.manager.pop.repository;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.smart.common.entities.core.Page;
import com.smart.manager.member.entities.models.MemberProfileMain;
import com.smart.manager.member.entities.models.query.QMemberProfileMain;
import com.smart.manager.member.entities.views.query.QMemberView;
import com.smart.manager.pop.entities.assembler.AgentRequest;
import com.smart.manager.pop.entities.assembler.DsRule;
import com.smart.manager.pop.entities.body.RDisInviter;
import com.smart.manager.pop.entities.enums.BillKind;
import com.smart.manager.pop.entities.enums.BillState;
import com.smart.manager.pop.entities.models.PopDisBill;
import com.smart.manager.pop.entities.models.PopDisInviter;
import com.smart.manager.pop.entities.models.PopDisLevel;
import com.smart.manager.pop.entities.models.query.QPopDisInviter;
import com.smart.manager.pop.entities.models.query.QPopDisLevel;
import com.smart.manager.pop.entities.views.InviterView;
import com.smart.service.remind.RemindService;
import com.smart.utils.WorkAcl;
import io.ebean.DB;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 支付中心-订单管理
 *
 * @author Administrator
 */

@Log4j2
@Service
@RequiredArgsConstructor
public class DisInviterRepository {

    private final RemindService remindService;


    public Page<PopDisInviter> pageList(RDisInviter.SearchBody search) {

        QPopDisInviter query = new QPopDisInviter();
        query.setFirstRow(search.firstRow()).setMaxRows(search.maxRows()).order();
        return new Page<PopDisInviter>().load(query.findPagedList());
    }

    /**
     * 添加
     *
     * @param form 形式
     */
    public void add(RDisInviter.EditBody form) {
        PopDisInviter one = new QPopDisInviter().phone.eq(form.getPhone()).setMaxRows(1).findOne();
        Assert.isNull(one, "手机号已存在");
        PopDisInviter record = BeanUtil.copyProperties(form, PopDisInviter.class);
        record.setAmount(BigDecimal.ZERO)   //设置金额
                .setAmountCont(BigDecimal.ZERO) //设置总金额
                .setDepositFee(BigDecimal.ZERO) //设置总金额
                .setStatus(form.getState())  //设置状态PopDisInviter
                .setAvatar(form.getAvatar()) //设置默认头像
                .setOpenid(null)  //设置openid
                .setLevel(form.getLevel())  //设置为普通用户
                .setRts1(0).setRts2(0)
                .setImage(new ArrayList<>())
                .setImageUser(new ArrayList<>())
                .setName(form.getName());
        record.save();
    }

    /**
     * 更新
     *
     * @param id   id
     * @param form 形式
     */
    public void update(Long id, RDisInviter.EditBody form) {
        PopDisInviter record = new QPopDisInviter().id.eq(id).findOne();
        Assert.notNull(record, "分销人员档案信息 不存在");
        BeanUtil.copyProperties(form, record);
        record.update();
    }


    /**
     * @param agent  触发人
     * @param kind   类型
     * @param amount 触发金额
     * @param remark 备注
     */
    public PopDisBill addBill(InviterView agent, BillKind kind, BigDecimal amount, String remark, Boolean isGold) {

        PopDisBill popDisBill = null;
        //判断是否是金币
        if (isGold) {
            amount = NumberUtil.div(amount, 100);
        }
        //先获取推广员的信息
        PopDisInviter inviter = getOneById(agent.getId());
        Assert.isTrue(amount.compareTo(BigDecimal.ZERO) > 0, "操作的金额必须大于0");
        //受益 类型
        List<BillKind> kinds = List.of(BillKind.SYSTEM, BillKind.WITHDRAW);
        if (kinds.contains(kind)) {
            BigDecimal decimal = inviter.getAmount().subtract(amount);
            Assert.isTrue(decimal.compareTo(BigDecimal.ZERO) >= 0, "余额不足扣除失败!");
            inviter.setAmount(decimal).update();
            popDisBill = new PopDisBill().setCode(generateTradeNo()).setAgent(agent).setKind(kind).setStatus(BillState.EXPENDITURE).setAmount(amount).setRemark(remark);
        } else {
            BigDecimal added = inviter.getAmount().add(amount);
            BigDecimal addCont = inviter.getAmountCont().add(added);
            inviter.setAmount(added).setAmountCont(addCont).update();
            popDisBill = new PopDisBill().setCode(generateTradeNo()).setAgent(agent).setKind(kind).setStatus(BillState.REVENUE).setAmount(amount).setRemark(remark);
        }
        popDisBill.insert();
        return popDisBill;
    }


    /**
     * 玩家消费 验证
     *
     * @param phoneNumber 游戏玩家
     * @param kind        消费类型
     * @param gold        消费金币
     */
    public void buyPig(String phoneNumber, BillKind kind, BigDecimal gold) {
        Optional<MemberProfileMain> relation = new QMemberProfileMain().phoneNumber.eq(phoneNumber).setMaxRows(1).findOneOrEmpty();
        //纯在关系 则计算
        relation.ifPresent(x -> {
            Optional<PopDisInviter> oneOrEmpty = new QPopDisInviter().id.eq(x.getInviterId()).findOneOrEmpty();
            oneOrEmpty.ifPresent(agentMain -> {
                InviterView agent = BeanUtil.copyProperties(agentMain, InviterView.class);
                Optional<PopDisLevel> levelOptional = new QPopDisLevel().id.eq(agent.getLevel().getId()).findOneOrEmpty();
                levelOptional.ifPresent(c -> {
                    DsRule rule = c.getRule();
                    String phone = DesensitizedUtil.mobilePhone(phoneNumber);
                    //换算消费的金币等于 的 人民币
                    switch (kind) {
                        case RAISE:
                            //认养猪仔
                            //换算为钱的数据
                            BigDecimal sub = NumberUtil.round(NumberUtil.mul(NumberUtil.div(rule.getMzTcBfb().intValue(), 100), gold),2);
                            PopDisBill popDisBill = addBill(agent, kind, sub, "您邀请的" + phone + "用户认养了一头猪获得佣金" + sub + "元", false);
                            remindService.sendStreamBind(agentMain, popDisBill);
                            break;
                        case EATING:
                        case CONSUME:
                            //日常喂养
                            BigDecimal sub2 = NumberUtil.round(NumberUtil.mul(NumberUtil.div(rule.getWyTcBfb().intValue(), 100), gold),2);
                            PopDisBill popDisBill2 = addBill(agent, kind, sub2, "您邀请的" + phone + "用户日常消费中获得佣金" + sub2 + "元", false);
                            remindService.sendStreamBind(agentMain, popDisBill2);
                            break;
                    }
                });
            });
        });
    }


    /**
     * 排名列表
     *
     * @return {@link List}<{@link PopDisInviter}>
     */
    public AgentRequest.leaderboard listRanking() {
        Long loginId = WorkAcl.getLoginId();
        List<PopDisInviter> list = new QPopDisInviter().order().amountCont.desc().setMaxRows(10).findList();
        List<InviterView> inviterViews = BeanUtil.copyToList(list, InviterView.class);
        PopDisInviter userOne = new QPopDisInviter().id.eq(loginId).setMaxRows(1).findOne();
        InviterView copyProperties = BeanUtil.copyProperties(userOne, InviterView.class);
        List<Long> collect = inviterViews.stream().map(InviterView::getId).collect(Collectors.toList());
        AgentRequest.leaderboard agentRequest = new AgentRequest.leaderboard();
        if (collect.contains(loginId)) {
            agentRequest.setMyPosition(String.valueOf(collect.indexOf(loginId) + 1));
        } else {
            agentRequest.setMyPosition("未上榜");
        }
        return agentRequest.setRankingOne(copyProperties).setRanking(inviterViews);
    }


    /**
     * 我的团队列表
     * TODO:统计有问题
     *
     * @param id id
     * @return {@link AgentRequest.myTeam}
     */
    public AgentRequest.myTeam AgentUserList(Long id) {
        List<PopDisInviter> list = new QPopDisInviter().parentId.eq(id).order().amountCont.desc().findList();
        list.forEach(x -> {
            x.setPhone(DesensitizedUtil.mobilePhone(x.getPhone()));//脱敏
        });
        List<InviterView> inviterViews = BeanUtil.copyToList(list, InviterView.class);
        BigDecimal zero = BigDecimal.ZERO;
        List<BigDecimal> collect = list.stream().map(PopDisInviter::getAmountCont)
                .collect(Collectors.toList());
        for (BigDecimal decimal : collect) {
            zero = zero.add(decimal);
        }
        return new AgentRequest.myTeam().setTeam(inviterViews).setTeamSize(list.size()).setAmountCont(zero);
    }


    /**
     * 我的玩家团队列表
     *
     * @param id id
     * @return {@link AgentRequest.myTeam}
     */
    public AgentRequest.myUserTeam UserList(Long id) {
        List<AgentRequest.myUser> list = new QMemberView().inviterId.eq(id).asDto(AgentRequest.myUser.class).setRelaxedMode().findList();
        int conts = 0;
        for (AgentRequest.myUser user : list) {
            String sql = "SELECT SUM(t0.event_total) AS cont \n" +
                    "FROM member_coin_bill AS t0 \n" +
                    "WHERE t0.member = " + user.getId() +
                    "AND (t0.event = 'DEDUCT' OR t0.event = 'BUYPIG' OR t0.event = 'SHOPOUT' OR t0.event = 'AUTOMATIC');\n";
            Integer cont = Objects.requireNonNull(DB.sqlQuery(sql).findOne()).getInteger("cont");
            int abs = Math.abs(cont);
            user.setTheAmountSpent(abs);
            conts += abs;
        }
        return new AgentRequest.myUserTeam().setTeam(list).setTeamSize(list.size()).setAmountCont(new BigDecimal(conts));
    }


    /**
     * 批量删除
     *
     * @param idList id列表
     * @return int
     */
    public int delByIds(List<Long> idList) {
        return DB.deleteAll(PopDisInviter.class, idList);
    }


    /**
     * 通过手机手机号查找代理
     *
     * @param phoneNumber
     * @return {@link PopDisInviter}
     */
    public PopDisInviter findByPhoneNumber(String phoneNumber) {
        return new QPopDisInviter().phone.eq(phoneNumber).setMaxRows(1).findOne();

    }

    /**
     * 通过id查找代理
     *
     * @param inviterId
     * @return {@link PopDisInviter}
     */
    public PopDisInviter getOneById(Long inviterId) {
        return new QPopDisInviter().id.eq(inviterId).setMaxRows(1).findOne();
    }


    /**
     * 生成订单id 长度为25个随机字符串
     *
     * @return {@code String}
     */
    private String generateTradeNo() {
        String x = DateUtil.format(new Date(), "yyyyMMddHHmmss").concat(RandomUtil.randomNumbers(5));
        return "TZ".concat(x);
    }
}
